<?php
declare (strict_types=1);

namespace app\controller;

use app\BaseController;
use app\common\Amap;
use app\common\UsersService;
use app\model\Activity;
use app\model\ActivityClass;
use app\model\ActivityComment;
use app\model\ActivityListen;
use app\model\ActivityMall;
use app\model\Config;
use app\model\Notice;
use app\model\Users;
use app\model\UsersRelated;
use app\model\UsersShield;
use app\Request;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\db\Query;
use think\Exception;
use think\response\Json;

class ActivityController extends BaseController
{
	
	protected array $middleware = [
		'Login' => ['except' => ['index', 'class', 'unpack', 'test', 'notice', 'read', 'comment_list', 'mall']],
		'Location' => ['only' => ['index', 'read']],
	];
	
	/**
	 * 屏蔽
	 * @param Request $request
	 * @return void
	 */
	function shield(Request $request)
	{
		$id = $request->post('id/d');
		UsersShield::create([
			'users_id'=>$request->users_id,
			'pro_id'=>$id,
			'type'=>'activity'
		]);
		writeJson();
	}
	
	/**
	 * 列表
	 * @param int $type
	 * @param string $keyword
	 * @param int $default
	 * @param mixed $class_id
	 * @param mixed $mall_id
	 * @return Json
	 */
	public function index(Request $request,int $type, string $keyword, int $default, mixed $class_id, mixed $mall_id): Json //type 类型:1=线上活动,2=线下活动 //default  0 默认排序  1最热 2最新 3距离最近
	{
		$shield = UsersShield::where(['users_id'=>$request->users_id,'type'=>'activity'])->column('pro_id');
		$lat = self::$latitude;
		$lng = self::$longitude;
		$rows = Activity::field("*,(6371 * acos (cos ( radians($lat) ) * cos( radians( lat ) ) * cos( radians(lng) - radians( $lng ) ) + sin ( radians( $lat ) ) * sin( radians( lat ) ))) AS distance")
			->whereNotIn('id',$shield)
			->where(['type' => $type, 'status' => 1])
			->when(!empty($keyword), function (Query $query) use ($keyword) {
				$query->whereLike('title', '%' . $keyword . '%');
			})
			->when(!empty($type), function (Query $query) use ($type) {
				if ($type == 1) {
					$query->field('min(price) as price')->group('goods_pd,mall,id');
				}
			})
			->when(!empty($default), function (Query $query) use ($default, $lat, $lng) {
				switch ($default) {
					case 1:
						$query->order('id', 'desc');
						break;
					case 2:
						$query->order('browse', 'desc');
						break;
					case 3:
						$query->order('createtime', 'desc');
						break;
					case 4:
						$query->where('images', '<>', '');
						break;
					case 5:
						if (empty($lat) || empty($lng)) {
							$query->order('createtime', 'desc');
						} else {
							$query->order('distance', 'asc');
						}
						break;
				}
			})
			->when(!empty($class_id), function (Query $query) use ($class_id) {
				$query->where('class_id', $class_id);
			})
			->when(!empty($mall_id), function (Query $query) use ($mall_id) {
				$query->where('mall_id', $mall_id);
			})
			->filter(function ($data) use ($lat, $lng) {
				if (empty($lat) || empty($lng)) {
					$data->distance_text = '';
				} else {
					if (empty($data->latitude) || empty($data->longitude)) {
						$data->distance_text = '';
					} else {
						if ($data->distance == 0) {
							$data->distance_text = '0m';
						} elseif (0 < $data->distance && $data->distance < 1) {
							$data->distance_text = bcmul((string)$data->distance, '1000') . 'm';
						} else {
							$data->distance_text = bcmul((string)$data->distance, '1', 1) . 'km';
						}
					}
				}
			})
			->order(['id' => 'desc'])
			->paginate()
			->items();
		writeJson($rows);
		
	}
	
	
	/**
	 * 发布
	 * @param Request $request
	 * @return \think\response\Json
	 */
	public function save(Request $request)
	{
		$params = $request->param();
		$params['score'] = Config::getFieldByName('activity_score', 'value');
		if (empty($params['id'])) {
			$row = Activity::create($params);
		} else {
			$row = Activity::find($params['id']);
			$row->status = 0;
			$row->save($params);
		}
		writeJson($row);
	}
	
	/**
	 * 详情
	 * @param int $id
	 * @param Request $request
	 * @return Json
	 */
	public function read(int $id, Request $request)
	{
		$lat = self::$latitude;
		$lng = self::$longitude;
		$row = Activity::field("*,(6371 * acos (cos ( radians($lat) ) * cos( radians( lat ) ) * cos( radians(lng) - radians( $lng ) ) + sin ( radians( $lat ) ) * sin( radians( lat ) ))) AS distance")
			->with([
				'users',
				'users_collect' => function (Query $query) use ($request) {
					$query->where(['users_id' => $request->users_id, 'type' => 'activity']);
				},
				'users_like' => function (Query $query) use ($request) {
					$query->where(['users_id' => $request->users_id, 'type' => 'activity']);
				}
			])
			->filter(function ($data) use ($lat, $lng) {
				if ($data->type == 2) {
					if (empty($lat) || empty($lng)) {
						$data->distance_text = '';
					} else {
						if (empty($data->latitude) || empty($data->longitude)) {
							$data->distance_text = '';
						} else {
							if ($data->distance == 0) {
								$data->distance_text = '0m';
							} elseif (0 < $data->distance && $data->distance < 1) {
								$data->distance_text = bcmul((string)$data->distance, '1000') . 'm';
							} else {
								$data->distance_text = bcmul((string)$data->distance, '1', 1) . 'km';
							}
						}
					}
				}
			})
			->findOrFail($id);
		UsersService::footmark($id, $request->users_id, 'activity');
		
		$class1 = ActivityClass::find($row->class_id);
		$class1_name = $class1 ? $class1->name : '';
		$class2 = ActivityClass::find($class1->pid);
		$class2_name = $class2 ? $class2->name : '';
		$class3 = ActivityClass::find($class2->pid);
		$class3_name = $class3 ? $class3->name : '';
		$row->class = $class3_name . '-' . $class2_name . '-' . $class1_name;
		event('ActivityIncBrowse', $id); //增加浏览数量
		writeJson($row);
	}
	
	
	/**
	 * 评论列表
	 * @param int $activity_id
	 * @param mixed $comment_id
	 * @param Request $request
	 * @return Json
	 */
	function comment_list(int $activity_id, mixed $comment_id, Request $request)
	{
		$top_id = 0;
		if (!empty($comment_id)) {
			$row = ActivityComment::find($comment_id);
			if ($row->pid == 0) {
				//顶级评论 放在第一条
				$top_id = $row->id;
			} else {
				//子评论 找出顶级评论
				$row = ActivityComment::find($row->pid);
				$top_id = $row->id;
			}
		}
		$rows = ActivityComment::where(['pid' => 0, 'activity_id' => $activity_id])
			->withCount('comment')
			->with([
				'users',
				'users_like' => function (Query $query) use ($request) {
					$query->where(['users_id' => $request->users_id, 'type' => 'activity_comment']);
				},
				'comment' => function (Query $query) use ($request, $comment_id) {
					$query
						->with(['users', 'to_users', 'users_like' => function (Query $query) use ($request) {
							$query->where(['users_id' => $request->users_id, 'type' => 'activity_comment']);
						}])
						->when(!empty($comment_id), function (Query $query) use ($comment_id) {
							$query->field("*,IF(id = $comment_id,1,0) AS top")->order(['top' => 'desc', 'id' => 'desc']);
						}, function (Query $query) {
							$query->order(['id' => 'desc']);
						})
						->limit($this->comment_list_rows);
				}])
			->when(!empty($comment_id), function (Query $query) use ($top_id) {
				$query->field("IF(id = $top_id,1,0) AS top")->order(['top' => 'desc', 'id' => 'desc']);
			}, function (Query $query) {
				$query->order(['id' => 'desc']);
			})
			->paginate()
			->items();
		writeJson($rows);
	}
	
	
	/**
	 * 评论详情
	 * @param int $id
	 * @param Request $request
	 * @return Json
	 */
	function comment_detail(int $id, mixed $comment_id, Request $request)
	{
		$child = false;
		if (!empty($comment_id)) {
			$row = ActivityComment::find($comment_id);
			if ($row->pid != 0) {
				//二级评论
				$child = true;
			}
		}
		
		$rows = ActivityComment::with([
			'users',
			'to_users',
			'users_like' => function (Query $query) use ($request) {
				$query->where(['users_id' => $request->users_id, 'type' => 'activity_comment']);
			},
		])
			->when($child, function (Query $query) use ($comment_id) {
				$query->where('id', '<>', $comment_id);
			})
			->where(['pid' => $id])
			->order(['id' => 'desc'])
			->paginate($this->comment_detail_rows)
			->items();
		writeJson($rows);
	}
	
	/**
	 * 评论
	 * @param Request $request
	 * @return Json
	 */
	function comment(Request $request): Json
	{
		$params = $request->param();
		$ip = $request->ip();
		$params['ip'] = $ip;
		$ip = Amap::ip($ip);
		$ip = json_decode($ip);
		if ($ip->status == 1) {
			$params['city'] = $ip->province;
		} else {
			$params['city'] = '未知';
		}
		$res = ActivityComment::create($params);
		foreach ($params['content'] as $v) {
			if ($v['type'] == 'at') {
				//@提醒  提醒接收人
				UsersRelated::create(['users_id' => $v['userId'], 'type' => 8, 'from_users_id' => $request->users_id, 'scene' => 'Activity', 'pro_id' => $res->id]);
			}
		}
		if (!empty($params['to_users_id'])) {
			//回复提醒  提醒接收人
			UsersRelated::create(['users_id' => $params['to_users_id'], 'type' => 1, 'from_users_id' => $request->users_id, 'scene' => 'Activity', 'pro_id' => $res->id]);
		} else {
			//评论提醒  提醒发布人
			$pro = Activity::find($params['activity_id']);
			UsersRelated::create(['users_id' => $pro->users_id, 'type' => 2, 'from_users_id' => $request->users_id, 'scene' => 'Activity', 'pro_id' => $res->id]);
		}
		event('ActivityIncComment', $params['activity_id']); //增加评论数量
		$row = ActivityComment::with(['users', 'to_users', 'users_like' => function (Query $query) use ($request) {
			$query->where(['users_id' => $request->users_id, 'type' => 'activity_comment']);
		}])->find($res->id);
		writeJson($row);
	}
	
	
	/**
	 * 类目
	 */
	function class()
	{
		$rows = ActivityClass::with(['class_id' => function (Query $query) {
			$query->with(['class_id' => function (Query $query) {
				$query->with(['class_id']);
			}]);
		}])->where(['pid' => 0])->select();
		writeJson($rows);
	}
	
	/**
	 * 解析口令链接
	 */
	function unpack(Request $request)
	{
		$short_link = $request->post('short_link');
		try {
			$res = \app\common\Activity::unpack($short_link);
		} catch (Exception $e) {
			writeJson(0, $e->getMessage());
		}
		writeJson($res);
	}
	
	/**
	 * 监控价格
	 * @param Request $request
	 * @return Json
	 * @throws DataNotFoundException
	 * @throws DbException
	 * @throws ModelNotFoundException
	 */
	function listen(Request $request)
	{
		$mall = $request->post('mall');
		$goods_pd = $request->post('goods_pd');
		$amount = $request->post('amount');
		$ActivityListenModel = new ActivityListen();
		$row = $ActivityListenModel->where(['users_id' => $request->users_id, 'mall' => $mall, 'goods_pd' => $goods_pd])->find();
		$nickname = Users::getFieldById($request->users_id, 'nickname');
		if ($row) {
			$row->amount = $amount;
			$row->save();
		} else {
			$ActivityListenModel->users_id = $request->users_id;
			$ActivityListenModel->mall = $mall;
			$ActivityListenModel->goods_pd = $goods_pd;
			$ActivityListenModel->amount = $amount;
			$ActivityListenModel->save();
			//通知信息
			Notice::create(['type' => 2, 'users_id' => $request->users_id, 'content' => $nickname . ' 开始监控价格', 'pro_id' => $ActivityListenModel->id]);
		}
		writeJson();
	}
	
	/**
	 * 动态广播
	 * @return Json
	 */
	function notice()
	{
		$rows = Notice::where(['type' => 2])->limit($this->page_rows)->order(['id' => 'desc'])->select();
		writeJson($rows);
	}
	
	/**
	 * 取消监听
	 * @return Json
	 */
	function cancel_listen(Request $request)
	{
		$id = $request->post('id/d');
		ActivityListen::destroy($id);
		writeJson();
	}
	
	/**
	 * 查询历史记录
	 * @param int $type
	 * @param $mall
	 * @param $goods_pd
	 * @param Request $request
	 * @return Json
	 */
	function history(int $type, $mall, $goods_pd, Request $request)//type 1=360天 2=180天 3=60天 4=30天
	{
		$start = time();
		$zuidi = Activity::where(['mall' => $mall, 'type' => 1, 'goods_pd' => $goods_pd, 'status' => 1])->min('price');
		$date = [];
		$price = [];
		$min_price = [];
		$first_price = [];
		$first = Activity::where(['mall' => $mall, 'type' => 1, 'goods_pd' => $goods_pd, 'status' => 1])->order(['id' => 'asc'])->value('price');
		switch ($type) {
			case 1:
				$min = Activity::where(['mall' => $mall, 'type' => 1, 'goods_pd' => $goods_pd, 'status' => 1])->whereTime('createtime', '-360 day')->order(['price' => 'asc'])->value('price');
				
				for ($i = 360; $i >= 0; $i--) {
					$date[] = date('m-d', strtotime('-' . $i . 'day'));
					$min_price[] = (float)$min;
					$first_price[] = (float)$first;
					
					
					$row = Activity::where(['mall' => $mall, 'type' => 1, 'goods_pd' => $goods_pd, 'status' => 1])->whereDay('createtime', date('Y-m-d', strtotime('-' . $i . 'day')))->order(['price' => 'asc'])->find();
					if (empty($row)) {
						$price[] = $i == 0 && isset($min) ? (float)$min : null;
					} else {
						$price[] = (float)$row->price;
					}
				}
				break;
			case 2:
				$min = Activity::where(['mall' => $mall, 'type' => 1, 'goods_pd' => $goods_pd, 'status' => 1])->whereTime('createtime', '-180 day')->order(['price' => 'asc'])->value('price');
				
				for ($i = 180; $i >= 0; $i--) {
					$date[] = date('m-d', strtotime('-' . $i . 'day'));
					$min_price[] = (float)$min;
					$first_price[] = (float)$first;
					$row = Activity::where(['mall' => $mall, 'type' => 1, 'goods_pd' => $goods_pd, 'status' => 1])->whereDay('createtime', date('Y-m-d', strtotime('-' . $i . 'day')))->order(['price' => 'asc'])->find();
					if (empty($row)) {
						$price[] = $i == 0 && isset($min) ? (float)$min : null;
					} else {
						$price[] = (float)$row->price;
					}
				}
				break;
			case 3:
				$min = Activity::where(['mall' => $mall, 'type' => 1, 'goods_pd' => $goods_pd, 'status' => 1])->whereTime('createtime', '-60 day')->order(['price' => 'asc'])->value('price');
				
				for ($i = 60; $i >= 0; $i--) {
					$date[] = date('m-d', strtotime('-' . $i . 'day'));
					$min_price[] = (float)$min;
					$first_price[] = (float)$first;
					$row = Activity::where(['mall' => $mall, 'type' => 1, 'goods_pd' => $goods_pd, 'status' => 1])->whereDay('createtime', date('Y-m-d', strtotime('-' . $i . 'day')))->order(['price' => 'asc'])->find();
					if (empty($row)) {
						$price[] = $i == 0 && isset($min) ? (float)$min : null;
					} else {
						$price[] = (float)$row->price;
					}
				}
				break;
			case 4:
				$min = Activity::where(['mall' => $mall, 'type' => 1, 'goods_pd' => $goods_pd, 'status' => 1])->whereTime('createtime', '-30 day')->order(['price' => 'asc'])->value('price');
				
				for ($i = 30; $i >= 0; $i--) {
					$date[] = date('m-d', strtotime('-' . $i . 'day'));
					$min_price[] = (float)$min;
					$first_price[] = (float)$first;
					$row = Activity::where(['mall' => $mall, 'type' => 1, 'goods_pd' => $goods_pd, 'status' => 1])->whereDay('createtime', date('Y-m-d', strtotime('-' . $i . 'day')))->order(['price' => 'asc'])->find();
					if (empty($row)) {
						$price[] = $i == 0 && isset($min) ? (float)$min : null;
					} else {
						$price[] = (float)$row->price;
					}
				}
				break;
		}
		$list = ['date' => $date, 'min_price' => $min_price, 'price' => $price, 'first_price' => $first_price];
		$listen = ActivityListen::where(['users_id' => $request->users_id, 'mall' => $mall, 'goods_pd' => $goods_pd])->find();
		$end = time();
		writeJson(['min_price' => $zuidi, 'list' => $list, 'listen' => $listen, 'start' => $start, 'end' => $end]);
	}
	
	/**
	 * 优惠信息
	 * @param string $mall
	 * @param string $goods_pd
	 * @return void
	 */
	function coupon(string $mall, string $goods_pd)
	{
		$coupon = Activity::with(['users'])
			->where(['mall' => $mall, 'type' => 1, 'goods_pd' => $goods_pd, 'status' => 1])
			->order(['id' => 'desc'])
			->paginate()
			->items();
		writeJson($coupon);
	}
	
	/**
	 * 查询监听状态
	 * @param Request $request
	 * @param string $mall
	 * @param string $goods_pd
	 * @return Json
	 */
	function listen_read(Request $request, string $mall, string $goods_pd)
	{
		$row = ActivityListen::where(['users_id' => $request->users_id, 'mall' => $mall, 'goods_pd' => $goods_pd])
			->find();
		writeJson($row);
	}
	
	/**
	 * 收藏
	 * @param Request $request
	 * @return Json
	 */
	function collect(Request $request)
	{
		$id = $request->post('id/d');
		$res = UsersService::collect($id, $request->users_id, 'activity');
		$res ? event('ActivityIncCollect', $id) : event('ActivityDecCollect', $id); //增加/减少  收藏数量
		if ($res) {
			$pro = Activity::find($id);
			UsersRelated::create(['users_id' => $pro->users_id, 'type' => 7, 'from_users_id' => $request->users_id, 'scene' => 'Activity', 'pro_id' => $id]);
		}
		writeJson($res);
	}
	
	/**
	 * 点赞
	 * @param Request $request
	 * @return Json
	 */
	function like(Request $request)
	{
		$id = $request->post('id');
		$res = UsersService::like($id, $request->users_id, 'activity');
		$res ? event('ActivityIncLike', $id) : event('ActivityDecLike', $id); //增加/减少  点赞数量
		if ($res) {
			$pro = Activity::find($id);
			UsersRelated::create(['users_id' => $pro->users_id, 'type' => 3, 'from_users_id' => $request->users_id, 'scene' => 'Activity', 'pro_id' => $id]);
		}
		writeJson($res);
	}
	
	
	/**
	 * 评论点赞
	 * @param Request $request
	 * @return Json
	 */
	function comment_like(Request $request)
	{
		$id = $request->param('id');
		$res = UsersService::like($id, $request->users_id, 'activity_comment');
		$res ? event('ActivityCommentIncLike', $id) : event('ActivityCommentDecLike', $id); //增加/减少  点赞数量
		if ($res) {
			$pro = ActivityComment::find($id);
			UsersRelated::create(['users_id' => $pro->users_id, 'type' => 4, 'from_users_id' => $request->users_id, 'scene' => 'Activity', 'pro_id' => $id]);
		}
		writeJson($res);
	}
	
	/**
	 * 我的爆料
	 * @param Request $request
	 * @param int $type
	 * @param int $status
	 * @return Json
	 */
	function my_activity(Request $request, int $type, int $status)
	{
		$rows = Activity::where(['type' => $type, 'users_id' => $request->users_id])
			->when(in_array($status, [0, 1, 2, 3]), function (Query $query) use ($status) {
				$query->where(['status' => $status]);
			})
			->order(['id' => 'desc'])
			->paginate()
			->items();
		writeJson($rows);
	}
	
	/**
	 * 撤销审核
	 * @param int $id
	 * @return Json
	 */
	function revoke(int $id)
	{
		Activity::where(['id' => $id])->update(['status' => 3]);
		writeJson();
	}
	
	/**
	 * 删除
	 * @return Json
	 */
	function delete(Request $request)
	{
		$id = $request->post('id/d');
		Activity::where(['users_id' => $request->users_id, 'id' => $id])->findOrFail()->delete();
		writeJson();
	}
	
	/**
	 * 重新提交
	 * @param int $id
	 * @return Json
	 */
	function repost(int $id, Request $request)
	{
		$ActivityModel = new Activity();
		$row = Activity::findOrFail($id);
		if (!$request->isPost()) {
			writeJson($row);
		}
		$params = $request->param();
		$row->save($params);
		writeJson();
	}
	
	
	/**
	 * 精选
	 * @return Json
	 */
	function fine()
	{
		$rows = Activity::where(['type' => 1, 'status' => 1])->limit(10)->order(['like' => 'desc'])->select();
		writeJson($rows);
	}
	
	/**
	 * 平台列表
	 * @return Json
	 */
	function mall()
	{
		$rows = ActivityMall::order(['weigh' => 'desc'])->select();
		writeJson($rows);
	}
	
	
}
